﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;

using Styx.WoWInternals.DBC;
using Styx.WoWInternals.WoWObjects;
using Styx.WoWInternals;
using Styx.Common;
using Styx.CommonBot.Routines;
using Styx.Helpers;
using Styx.Pathing;
using Styx;
using System.Diagnostics;
using System.Threading;
using System.IO;
using Styx.CommonBot;
using System.Windows.Forms;
using Styx.CommonBot.Inventory;

namespace KingWoW
{
    class CombatRogueCombatClass : KingWoWAbstractBaseClass
    {

        private static string Name = "KingWoW CombatRogue'";

        #region CONSTANT AND VARIABLES

        //START OF CONSTANTS ==============================
        private const bool LOGGING = true;
        private const bool DEBUG = false;
        private const bool TRACE = false;
        private KingWoWUtility utils = null;
        private Movement movement = null;
        private ExtraUtils extra = null;

        private WoWUnit tank = null;
        private WoWUnit lastTank = null;
        private bool SoloBotType = false;
        private string BaseBot = "unknown";
        private TalentManager talents = null;

        private const string DEBUG_LABEL = "DEBUG";
        private const string TRACE_LABEL = "TRACE";
        private const string TANK_CHANGE = "TANK CHANGED";
        private const string FACING = "FACING";
        private DateTime nextTimeRedirectAllowed;

     

        //START OF SPELLS AND AURAS ==============================
        private const string DRINK = "Drink";
        private const string FOOD = "Food";

        private const int adrenaline_rush = 13750;
	    private const int adrenaline_rush_buff = 13750;
	    private const int ambush = 8676;
		private const int anticipation = 114015;
	    private const int anticipation_buff = 115189;
	    private const int backstab = 53;
	    private const int bandits_guile = 84654;
	    private const int bandits_guile_buff = 84654;
	    private const int blade_flurry = 13877;
	    private const int blade_flurry_buff = 13877;
	    private const int blindside = 121152;
	    private const int blindside_buff = 121153;
	    private const int cheap_shot = 1833;
	    private const int cloak_of_shadows = 31224;
	    private const int crimson_tempest = 121411;
	    private const int crimson_tempest_dot_debuff = 122233;
	    private const int crippling_poison = 3408;
	    private const int crippling_poison_buff = 3408;
	    private const int cut_to_the_chase = 51667;
	    private const int deadly_poison = 2823;
	    private const int deadly_poison_buff = 2823;
	    private const int deep_insight_buff = 84747;
        private const int moderate_insigh_buff = 84746;
        private const int shallow_insigh_buff = 84745;
        private const int dispatch = 111240;
	    private const int envenom = 32645;
	    private const int eviscerate = 2098;
	    private const int fan_of_knives = 51723;
	    private const int feint = 1966;
	    private const int find_weakness = 91023;
	    private const int find_weakness_debuff = 91021;
	    private const int hemorrhage_debuff = 89775;
	    private const int kick = 1766;
	    private const int kidney_shot = 408;
	    private const int killing_spree = 51690;
	    private const int leeching_poison = 108211;
	    private const int leeching_poison_buff = 108211;
	    private const int marked_for_death = 137619;
	    private const int master_of_subtlety_buff = 31665;
	    private const int mind_numbing_poison = 5761;
	    private const int mind_numbing_poison_buff = 5761;
	    private const int mutilate = 1329;
	    private const int paralytic_poison = 108215;
	    private const int paralytic_poison_buff = 108215;
	    private const int premeditation = 14183;
	    private const int preparation = 14185;
	    private const int redirect = 73981;
	    private const int revealing_strike = 84617;
	    private const int revealing_strike_debuff = 84617;
	    private const int rupture = 1943;
	    private const int rupture_debuff = 1943;
	    private const int seal_fate = 14190;
	    private const int shadow_blades = 121471;
	    private const int shadow_blades_buff = 121471;
	    private const int shadow_dance = 51713;
	    private const int shadow_dance_buff = 51713;
	    private const int shadow_focus = 108209;
	    private const int shuriken_toss = 114014;
	    private const int sinister_strike = 1752;
	    private const int sleight_of_hand_buff = 145211;
	    private const int slice_and_dice = 5171;
	    private const int slice_and_dice_buff = 5171;
	    private const int stealth = 1784;
	    private const int steath_buff = 11327;
	    private const int tricks_of_the_trade = 57934;
	    private const int vanish = 1856;
	    private const int vanish_buff = 11327;
	    private const int vendetta = 79140;
	    private const int wound_poison = 8679;
	    private const int wound_poison_buff = 8679;
	    private const int recuperate = 73651;
        private const int shadowstep = 36554;
        private const int sprint = 2983;
        private const int evasion = 5277;
        private const int combat_readiness = 74001;
        

        
          
        //END OF SPELLS AND AURAS ==============================

        //TALENTS
        
        //END TALENTS
        //END OF CONSTANTS ==============================

        #endregion

        public CombatRogueCombatClass()
        {
            utils = new KingWoWUtility();
            movement = new Movement();
            extra = new ExtraUtils();
            tank = null;
            lastTank = null;;
            SoloBotType = false;
            BaseBot = "unknown";
            talents = new TalentManager();
            nextTimeRedirectAllowed = DateTime.Now;
        }

        public void SetNextTimeRedirect()
        {
            //3 seconds wait to avoid popping 2 rune of frost cause has high priority
            nextTimeRedirectAllowed = DateTime.Now + new TimeSpan(0, 0, 0, 0, 3000);
        }

        public override bool Combat
        {
            get 
            {
                if (/*ExtraUtilsSettings.Instance.PauseRotation || */ !StyxWoW.IsInGame || !StyxWoW.IsInWorld || /*utils.IsGlobalCooldown(true) ||*/ utils.isAuraActive(DRINK) || utils.isAuraActive(FOOD) || Me.IsChanneling || utils.MeIsCastingWithLag())
                    return false;

                //UPDATE TANK
                //tank = utils.GetTank();
                tank = utils.SimpleGetTank(40f);
                //if (tank == null || !tank.IsValid || !tank.IsAlive) tank = Me;

                if (tank != null && (lastTank == null || lastTank.Guid != tank.Guid))
                {
                    lastTank = tank;
                    utils.LogActivityEnergy(TANK_CHANGE, tank.Class.ToString());
                }
                return CombatRotation();
            }
        }
       
        public override bool Pulse
        {
            get 
            {
                if (Me.IsDead) return MyDeath();
                if (/*ExtraUtilsSettings.Instance.PauseRotation || */ !StyxWoW.IsInGame || !StyxWoW.IsInWorld || /*utils.IsGlobalCooldown(true) ||*/ utils.isAuraActive(DRINK) || utils.isAuraActive(FOOD) || Me.IsChanneling || utils.MeIsCastingWithLag() || Me.Mounted)
                    return false;

                //UPDATE TANK
                //tank = utils.GetTank();
                tank = utils.SimpleGetTank(40f);
                //if (tank == null || !tank.IsValid || !tank.IsAlive) tank = Me;

                if (tank != null && (lastTank == null || lastTank.Guid != tank.Guid))
                {
                    lastTank = tank;
                    utils.LogActivityEnergy(TANK_CHANGE, tank.Class.ToString());
                }
                //redirect
                if (!Me.Combat && CombatRogueSettings.Instance.UseRedirect && nextTimeRedirectAllowed < DateTime.Now && Me.CurrentTarget != null && !Me.CurrentTarget.IsDead && !Me.CurrentTarget.IsFriendly && Me.CurrentTarget.Attackable && Me.RawComboPoints > 0 && Me.ComboPoints == 0 && utils.CanCast(redirect, Me.CurrentTarget, true))
                {
                    utils.LogActivityEnergy("redirect", Me.CurrentTarget.Name);
                    SetNextTimeRedirect();
                    utils.Cast(redirect, Me.CurrentTarget);
                }
                if(CombatRogueSettings.Instance.AutoUseVanish && utils.isAuraActive(vanish_buff)  
                    && Me.CurrentTarget != null && !Me.CurrentTarget.IsFriendly && Me.CurrentTarget.Attackable
                    && utils.CanCast(ambush, Me.CurrentTarget, true) && Me.CurrentTarget.IsWithinMeleeRange && (talents.IsSelected(10) || (!talents.IsSelected(10) && Me.CurrentTarget.MeIsBehind)))
                    {
                        utils.LogActivityEnergy("ambush", Me.CurrentTarget.Name);
                        return utils.Cast(ambush, Me.CurrentTarget);
                    }
                if (tank != null && tank.Combat && !Me.Combat)
                    return CombatRotation();
                return false; 
            }
        }

        private bool DispellMe()
        {
            if (Me.ActiveAuras.Any(a => a.Value.IsHarmful && a.Value.Spell.DispelType == WoWDispelType.Magic || a.Value.Spell.DispelType == WoWDispelType.Curse))
            {
                utils.LogActivityEnergy("Use Cloack of shadow to dispell me");
                return utils.Cast(cloak_of_shadows, Me);
            }
            return false;
        }

        private bool MyDeath()
        {
            if (SoloBotType && Me.IsDead && !Me.IsGhost)
            {

                int Delay = 3000;
                Thread.Sleep(Delay);
                Lua.DoString(string.Format("RunMacroText(\"{0}\")", "/script RepopMe()"));
            }
            return false;
        }


        public bool ApplyPoisons()
        {
            switch (CombatRogueSettings.Instance.LethalPoisonTypeToApply)
            {
                case CombatRogueSettings.LethalPoisonType.AUTO:
                    {
                        if (!Me.HasAura(deadly_poison) || (!Me.Combat && Me.GetAuraById(deadly_poison).TimeLeft.Minutes <= 10))
                        {
                            //utils.LogActivityEnergy("apply deadly_poison");
                            return utils.Cast(deadly_poison);
                        }
                        break;
                    }
                case CombatRogueSettings.LethalPoisonType.DEADLY:
                    {
                        if (!Me.HasAura(deadly_poison) || (!Me.Combat && Me.GetAuraById(deadly_poison).TimeLeft.Minutes <= 10))
                        {
                            //utils.LogActivityEnergy("apply deadly_poison");
                            return utils.Cast(deadly_poison);
                        }
                        break;
                    }
                case CombatRogueSettings.LethalPoisonType.WOUND:
                    {
                        if (!Me.HasAura(wound_poison) || (!Me.Combat && Me.GetAuraById(wound_poison).TimeLeft.Minutes <= 10))
                        {
                            //utils.LogActivityEnergy("apply wound_poison");
                            return utils.Cast(wound_poison);
                        }
                        break;
                    }
            }

            switch (CombatRogueSettings.Instance.NonLethalPoisonTypeToApply)
            {
                case CombatRogueSettings.NonLethalPoisonType.AUTO:
                    {
                        if (talents.IsSelected(8) && (!Me.HasAura(leeching_poison) || (!Me.Combat && Me.GetAuraById(leeching_poison).TimeLeft.Minutes <= 10)))
                        {
                            //utils.LogActivityEnergy("apply leeching_poison");
                            return utils.Cast(leeching_poison);
                        }
                        else if (!talents.IsSelected(8) && (!Me.HasAura(paralytic_poison) || (!Me.Combat && Me.GetAuraById(paralytic_poison).TimeLeft.Minutes <= 10)))
                        {
                            //utils.LogActivityEnergy("apply paralytic_poison");
                            return utils.Cast(paralytic_poison);
                        }
                        break;
                    }
                case CombatRogueSettings.NonLethalPoisonType.CRYPPLING:
                    {
                        if (!Me.HasAura(crippling_poison) || (!Me.Combat && Me.GetAuraById(crippling_poison).TimeLeft.Minutes <= 10))
                        {
                            //utils.LogActivityEnergy("apply crippling_poison");
                            return utils.Cast(crippling_poison);
                        }
                        break;
                    }
                case CombatRogueSettings.NonLethalPoisonType.MINDNUMBING:
                    {
                        if (!Me.HasAura(mind_numbing_poison) || (!Me.Combat && Me.GetAuraById(mind_numbing_poison).TimeLeft.Minutes <= 10))
                        {
                            //utils.LogActivityEnergy("apply mind_numbing_poison");
                            return utils.Cast(mind_numbing_poison);
                        }
                        break;
                    }
                case CombatRogueSettings.NonLethalPoisonType.PARALITYC:
                    {
                        if (!Me.HasAura(paralytic_poison) || (!Me.Combat && Me.GetAuraById(paralytic_poison).TimeLeft.Minutes <= 10))
                        {
                            //utils.LogActivityEnergy("apply paralytic_poison");
                            return utils.Cast(paralytic_poison);
                        }
                        break;
                    }
            }
            return false;
        }

        public override bool Pull
        {
            get
            {
                WoWUnit target = Me.CurrentTarget;
                if (target != null && target.IsDead)
                    Me.ClearTarget();
                else if (target != null && !target.IsFriendly && target.Attackable && !target.IsDead)
                {
                    if (!target.InLineOfSpellSight || target.Distance - target.CombatReach -1 > CombatRogueSettings.Instance.PullDistance)
                    {
                        movement.KingHealMove(target,movement.meelerange);
                    }
                    if (!Me.IsMoving && !Me.IsFacing(target))
                    {
                        Me.SetFacing(target);
                    }
                    //redirect
                    if (Me.CurrentTarget != null && !Me.CurrentTarget.IsDead && CombatRogueSettings.Instance.UseRedirect && nextTimeRedirectAllowed < DateTime.Now && !Me.CurrentTarget.IsFriendly && Me.CurrentTarget.Attackable && Me.RawComboPoints > 0 && Me.ComboPoints == 0 && utils.CanCast(redirect, Me.CurrentTarget, true))
                    {
                        utils.LogActivityEnergy("redirect", Me.CurrentTarget.Name);
                        SetNextTimeRedirect();
                        utils.Cast(redirect, Me.CurrentTarget);
                    }
                    if (CombatRogueSettings.Instance.UseShadowStep && talents.IsSelected(11)/*shadowstep*/ && utils.CanCast(shadowstep, target, true) 
                        &&  target.Distance - target.CombatReach -1 <= 25)
                    {
                        utils.LogActivityEnergy("shadowstep", target.Name);
                        utils.Cast(shadowstep, target);
                    }
                    if (Me.ComboPoints == 5 && utils.CanCast(eviscerate, target, true))
                    {
                        utils.LogActivityEnergy("eviscerate", target.Name);
                        return utils.Cast(eviscerate, target);
                    }
                    else if (utils.CanCast(ambush, target, true) && (talents.IsSelected(10) || (!talents.IsSelected(10) && Me.CurrentTarget.MeIsBehind)))
                    {
                        utils.LogActivityEnergy("ambush", target.Name);
                        return utils.Cast(ambush, target);
                    }
                    else if (!utils.isAuraActive(revealing_strike, target) && utils.CanCast(revealing_strike, target, true))
                    {
                        utils.LogActivityEnergy("revealing_strike", target.Name);
                        return utils.Cast(revealing_strike, target);
                    }
                    else if (utils.isAuraActive(revealing_strike, target) && utils.CanCast(sinister_strike, target, true))
                    {
                        utils.LogActivityEnergy("sinister_strike", target.Name);
                        return utils.Cast(sinister_strike, target);
                    }
                }
                return false;
            }
        }

        public override bool Initialize
        {
            get
            {
                Logging.Write("Ciao " + Me.Class.ToString());
                Logging.Write("Welcome to " + Name + " custom class");
                Logging.Write("Tanks All HonorBuddy Forum developers for code inspiration!");
                Logging.Write("Powered by Attilio76");
                BotEvents.OnBotStartRequested += new BotEvents.OnBotStartStopRequestedDelegate(BotEvents_OnBotStart);
                Lua.Events.AttachEvent("GROUP_ROSTER_UPDATE", UpdateGroupChangeEvent);
                Lua.Events.AttachEvent("PLAYER_TARGET_CHANGED", TargetChangedEvent);

                utils.FillParties();
                return true; ;
            }
        }

        private void TargetChangedEvent(object sender, LuaEventArgs args)
        {
            //redirect
            if (Me.CurrentTarget != null && !Me.CurrentTarget.IsDead && CombatRogueSettings.Instance.UseRedirect && nextTimeRedirectAllowed < DateTime.Now && !Me.CurrentTarget.IsFriendly && Me.CurrentTarget.Attackable && Me.RawComboPoints > 0 && Me.ComboPoints == 0 && utils.CanCast(redirect, Me.CurrentTarget, true))
            {
                utils.LogActivityEnergy("redirect", Me.CurrentTarget.Name);
                SetNextTimeRedirect();
                utils.Cast(redirect, Me.CurrentTarget);
            }
        }

        private void UpdateGroupChangeEvent(object sender, LuaEventArgs args)
        {
            Logging.Write("Update Groups composition");
            utils.FillParties();
        }

        void BotEvents_OnBotStart(EventArgs args)
        {
            talents.Update();
            BotUpdate();
        }

        public override bool NeedCombatBuffs { get { return Buff(); } }

        public override bool NeedPreCombatBuffs { get { return Buff(); } }

        public override bool NeedPullBuffs { get { return Buff(); } }

        public override bool NeedRest
        {
            get
            {
                if (Me.IsDead) return false;
                if ((utils.isAuraActive(DRINK) || utils.isAuraActive(FOOD)) && (Me.ManaPercent < 100 || Me.HealthPercent < 100))
                    return true;
                
                if (Me.HealthPercent <= CombatRogueSettings.Instance.HealthPercent &&
                !utils.isAuraActive(FOOD) && !Me.Combat && !Me.IsMoving && !utils.MeIsCastingWithLag())
                {
                    WoWItem myfood = Consumable.GetBestFood(false);
                    if (myfood != null)
                    {
                        utils.LogActivityEnergy("Eating");
                        Styx.CommonBot.Rest.DrinkImmediate();
                        return true;
                    }
                }
                return false;
            }
        }

        private bool Buff()
        {
            if (utils.Mounted() /*ExtraUtilsSettings.Instance.PauseRotation || */)
                return false;

            if (ApplyPoisons())
                return true;
            if (!Me.Combat && CombatRogueSettings.Instance.StayStealth && !Me.IsStealthed && !utils.isAuraActive(vanish_buff) && !utils.isAuraActive(stealth))
            {
                //utils.LogActivityEnergy("Go Stealth");
                return utils.Cast(stealth);
            }
            return false; 
        }

        private bool BotUpdate()
        {
            if (BaseBot.Equals(BotManager.Current.Name))
                return false;
            if (utils.IsBotBaseInUse("LazyRaider") || utils.IsBotBaseInUse("Tyrael"))
            {
                Logging.Write("Detected LazyRaider/tyrael:");
                Logging.Write("Disable all movements");
                SoloBotType = false;
                BaseBot = BotManager.Current.Name;
                return true;
            }

            if (utils.IsBotBaseInUse("Raid Bot"))
            {
                Logging.Write("Detected RaidBot:");
                Logging.Write("Disable all movements");
                SoloBotType = false;
                BaseBot = BotManager.Current.Name;
                return true;
            }


            if (utils.IsBotBaseInUse("BGBuddy"))
            {
                Logging.Write("Detected BGBuddy Bot:");
                Logging.Write("Enable PVP Rotation");
                SoloBotType = false;
                BaseBot = BotManager.Current.Name;
                return true;
            }

            Logging.Write("Base bot detected: " + BotManager.Current.Name);
            SoloBotType = true;
            BaseBot = BotManager.Current.Name;
            return true;


        }

        private bool HealMe()
        {
            if (Me.HealthPercent <= CombatRogueSettings.Instance.RecuperateHP && !utils.isAuraActive(recuperate) && Me.ComboPoints > 0)
            {
                utils.LogActivityEnergy("recuperate");
                return utils.Cast(recuperate);
            }
            return false;
        }

        private bool DefensiveCD()
        {
            if (Me.HealthPercent <= CombatRogueSettings.Instance.CoSHP && utils.CanCast(cloak_of_shadows))
            {
                utils.LogActivityEnergy("cloak_of_shadows");
                return utils.Cast(cloak_of_shadows);
            }
            if (Me.HealthPercent <= CombatRogueSettings.Instance.EvasionHP && utils.CanCast(evasion))
            {
                utils.LogActivityEnergy("evasion");
                return utils.Cast(evasion);
            }
            if (Me.HealthPercent <= CombatRogueSettings.Instance.CombatReadinessHP && utils.CanCast(combat_readiness))
            {
                utils.LogActivityEnergy("combat_readiness");
                return utils.Cast(combat_readiness);
            }
            return false;
        }
        private bool CombatRotation()
        {
            extra.UseHealthstone();
            extra.UseRacials();
            extra.UseTrinket1();
            extra.UseTrinket2();
            extra.UseEngineeringGloves();
            extra.UseLifeblood();
            extra.UseAlchemyFlask();
            extra.WaterSpirit();
            extra.LifeSpirit();
            if (CombatRogueSettings.Instance.UseDispell && DispellMe())
                return true;
            if (DefensiveCD())
                return true;
            if (HealMe())
                return true;
            

            WoWUnit target = null;
            if (CombatRogueSettings.Instance.TargetTypeSelected == CombatRogueSettings.TargetType.MANUAL)
                target = Me.CurrentTarget;
            else if (CombatRogueSettings.Instance.TargetTypeSelected == CombatRogueSettings.TargetType.AUTO)
            {
                target = utils.getTargetToAttack(40, tank);
            }
            else if (CombatRogueSettings.Instance.TargetTypeSelected == CombatRogueSettings.TargetType.SEMIAUTO)
            {
                target = Me.CurrentTarget;
                if (target == null || target.IsDead || !target.InLineOfSpellSight || target.Distance - target.CombatReach - 1 > 40)
                    target = utils.getTargetToAttack(40, tank);
            }
            if (target != null && !target.IsDead && target.InLineOfSpellSight && target.Distance - target.CombatReach - 1 <= 40)
            {
                if (CombatRogueSettings.Instance.TargetTypeSelected == CombatRogueSettings.TargetType.AUTO)
                    target.Target();
                if ((CombatRogueSettings.Instance.AutofaceTarget || SoloBotType) && !Me.IsMoving)
                {
                    Me.SetFacing(target);
                }

                if (CombatRogueSettings.Instance.AutoSpeed
                    && target.Distance - target.CombatReach - 1 >= CombatRogueSettings.Instance.AutoSpeedRange && utils.CanCast(sprint))
                {
                    utils.LogActivityEnergy("sprint");
                    utils.Cast(sprint);
                }
                int enemy_around_10 = utils.AllAttaccableEnemyMobsInRange(10).Count();
                int enemy_around_8 = utils.AllAttaccableEnemyMobsInRange(8).Count();
                int enemy_around_5 = utils.AllAttaccableEnemyMobsInRange(5).Count();

                //redirect
                if (CombatRogueSettings.Instance.UseRedirect && Me.CurrentTarget != null && !Me.CurrentTarget.IsDead && nextTimeRedirectAllowed < DateTime.Now && !Me.CurrentTarget.IsFriendly && Me.CurrentTarget.Attackable && Me.RawComboPoints > 0 && Me.ComboPoints == 0 && utils.CanCast(redirect, Me.CurrentTarget, true))
                {
                    utils.LogActivityEnergy("redirect", Me.CurrentTarget.Name);
                    SetNextTimeRedirect();
                    utils.Cast(redirect, Me.CurrentTarget);
                }
                if (CombatRogueSettings.Instance.UseShadowStep && !target.IsWithinMeleeRange && talents.IsSelected(11)/*shadowstep*/ && utils.CanCast(shadowstep, target, true)
                        && target.Distance - target.CombatReach - 1 <= 25)
                {
                    utils.LogActivityEnergy("shadowstep", target.Name);
                    utils.Cast(shadowstep, target);
                }

                if ( CombatRogueSettings.Instance.AutoInterrupt && (target.IsCasting || target.IsChanneling) && (target.CanInterruptCurrentSpellCast || !extra.IsTargetBoss()))
                {
                    //utils.LogActivityEnergy("TARGET CASTING TRY INTERRUPT");
                    if (!extra.IsTargetBoss() && (Me.IsStealthed || utils.isAuraActive(vanish_buff) || utils.isAuraActive(stealth)) && utils.CanCast(cheap_shot, target, true))
                    {
                        utils.LogActivityEnergy("cheap_shot", target.Name);
                        return utils.Cast(cheap_shot,target);
                    }
                    else if (target.IsWithinMeleeRange && utils.CanCast(kick, target, true) && target.CanInterruptCurrentSpellCast)
                    {
                        utils.LogActivityEnergy("kick", target.Name);
                        return utils.Cast(kick, target);
                    }
                    else if (!extra.IsTargetBoss() && Me.CurrentEnergy >= 25 && Me.ComboPoints > 0 && target.IsWithinMeleeRange && utils.CanCast(kidney_shot, target,true))
                    {
                        utils.LogActivityEnergy("kidney_shot", target.Name);
                        return utils.Cast(kidney_shot, target);
                    }
                    
                }

                //Blade Flurry
                if (CombatRogueSettings.Instance.EnableAOE && !utils.isAuraActive(blade_flurry) && (enemy_around_10 >= CombatRogueSettings.Instance.FanOfKnivesNum || enemy_around_8 >= CombatRogueSettings.Instance.CrimsonTempestNum || enemy_around_5 >= CombatRogueSettings.Instance.BladeFlurryNum) && utils.CanCast(blade_flurry))
                {
                    utils.LogActivityEnergy("blade_flurry");
                    return utils.Cast(blade_flurry);
                }
                else if (utils.isAuraActive(blade_flurry) && enemy_around_10 < CombatRogueSettings.Instance.FanOfKnivesNum && enemy_around_8 < CombatRogueSettings.Instance.CrimsonTempestNum && enemy_around_5 < CombatRogueSettings.Instance.BladeFlurryNum && utils.CanCast(blade_flurry))
                {
                    utils.LogActivityEnergy("Cancel blade_flurry");
                    WoWAura a = Me.GetAuraById(blade_flurry);
                    if (a != null && a.Cancellable)
                    {
                        a.TryCancelAura();
                        return true;
                    }
                }

                if (CombatRogueSettings.Instance.AutoUseVanish && (talents.IsSelected(10) || (!talents.IsSelected(10) && Me.CurrentTarget.MeIsBehind)) && utils.isMyAuraActive(revealing_strike, target) && (Me.ComboPoints <= 4 || utils.PlayerCountBuff(anticipation_buff) <= 4) && utils.CanCast(vanish) &&
                    !Me.IsStealthed && !utils.isAuraActive(vanish_buff) && !utils.isAuraActive(stealth) )
                {
                    utils.LogActivityEnergy("vanish", target.Name);
                    utils.Cast(vanish, target);
                }


                if (utils.CanCast(ambush, target, true) && (talents.IsSelected(10) || (!talents.IsSelected(10) && Me.CurrentTarget.MeIsBehind)))
                {
                    utils.LogActivityEnergy("ambush", target.Name);
                    return utils.Cast(ambush, target);
                }

                if (CombatRogueSettings.Instance.UseKillingSpee && Me.CurrentEnergy <= CombatRogueSettings.Instance.KillingSpeeAtEnergy && !utils.isAuraActive(adrenaline_rush) && !utils.isAuraActive(adrenaline_rush_buff) && utils.CanCast(killing_spree, target, true) && target.Distance - target.CombatReach - 1 <= 10)
                {
                    utils.LogActivityEnergy("killing_spree");
                    return utils.Cast(killing_spree);
                }

                if (target.IsWithinMeleeRange) UseCD();

                if ((!utils.isAuraActive(slice_and_dice) || Me.GetAuraById(slice_and_dice).TimeLeft.TotalMilliseconds <= 2500)
                    && !(utils.isAuraActive(deep_insight_buff) && Me.ComboPoints == 5 && Me.GetAuraById(deep_insight_buff).TimeLeft.TotalMilliseconds <= 1500) && Me.ComboPoints > 0 && utils.CanCast(slice_and_dice))
                {
                    utils.LogActivityEnergy("slice_and_dice");
                    return utils.Cast(slice_and_dice);
                }

                //Finisher AOE
                if (CombatRogueSettings.Instance.EnableAOE && utils.isAuraActive(blade_flurry) && Me.ComboPoints == 5)
                {
                    if (enemy_around_8 >= CombatRogueSettings.Instance.CrimsonTempestNum && utils.CanCast(crimson_tempest))
                    {
                        utils.LogActivityEnergy("crimson_tempest");
                        return utils.Cast(crimson_tempest);
                    }
                }

                //finischer SINGLE
                if (  ((talents.IsSelected(18) /*anticipation*/ && Me.ComboPoints == 5 && 
                      (utils.isAuraActive(deep_insight_buff)
                      || CombatRogueSettings.Instance.TryConserveAnticipationUntil == CombatRogueSettings.AnticipationFinalBuffType.NO_INSIGHT_BUFF
                      || (utils.isAuraActive(moderate_insigh_buff) && CombatRogueSettings.Instance.TryConserveAnticipationUntil != CombatRogueSettings.AnticipationFinalBuffType.DEEP_INSIGHT_BUFF)
                      || (utils.isAuraActive(shallow_insigh_buff) && CombatRogueSettings.Instance.TryConserveAnticipationUntil != CombatRogueSettings.AnticipationFinalBuffType.DEEP_INSIGHT_BUFF && CombatRogueSettings.Instance.TryConserveAnticipationUntil != CombatRogueSettings.AnticipationFinalBuffType.MODERATE_INSIGHT_BUFF)  
                      || utils.PlayerCountBuff(anticipation_buff) >= 4
                      || (utils.PlayerCountBuff(anticipation_buff) > 0 && Me.GetAuraById(anticipation_buff).TimeLeft.TotalMilliseconds <= 2000) ) )

                      || (!talents.IsSelected(18) /*anticipation*/ && Me.ComboPoints == 5)
                    ) && target.IsWithinMeleeRange)
                {
           
                    {
                        if (CombatRogueSettings.Instance.UseRupture 
                            && (utils.isAuraActive(deep_insight_buff) || CombatRogueSettings.Instance.RuptureAlwaysUP)
                            && !utils.isMyAuraActive(rupture,target) 
                            && utils.TimeToDeath(target) >= 26
                            && Me.ComboPoints >= 5
                            && !utils.isAuraActive(blade_flurry) && utils.CanCast(rupture))
                        {
                            utils.LogActivityEnergy("rupture",target.Name);
                            return utils.Cast(rupture,target);
                        }
                        else if (utils.CanCast(eviscerate))
                        {
                            utils.LogActivityEnergy("eviscerate", target.Name);
                            return utils.Cast(eviscerate, target);
                        }

                    }
                }

                if (CombatRogueSettings.Instance.EnableAOE && Me.ComboPoints < 5 && enemy_around_10 >= CombatRogueSettings.Instance.FanOfKnivesNum && utils.CanCast(fan_of_knives))
                {
                    utils.LogActivityEnergy("fan_of_knives");
                    return utils.Cast(fan_of_knives);
                }

                else if ( target.IsWithinMeleeRange && (Me.ComboPoints < 5 || (talents.IsSelected(18) && utils.PlayerCountBuff(anticipation_buff) < 4 ) ))
                {
                    if( (!utils.isMyAuraActive(revealing_strike,target) || utils.MyAuraTimeLeft(revealing_strike,target) <= 2000 ) && utils.CanCast(revealing_strike,target,true))
                    {
                        utils.LogActivityEnergy("revealing_strike", target.Name);
                        return utils.Cast(revealing_strike, target);
                    }
                    else if (utils.CanCast(sinister_strike,target,true))
                    {
                        utils.LogActivityEnergy("sinister_strike", target.Name);
                        return utils.Cast(sinister_strike, target);
                    }
                }

                if (ExtraUtilsSettings.Instance.movementEnabled && ( !target.InLineOfSpellSight || !target.IsWithinMeleeRange))
                {
                    movement.KingHealMove(target, movement.meelerange);
                }
                

                if(!Me.IsAutoAttacking)
                    Lua.DoString("/startattack");

                
            }
            else if (ExtraUtilsSettings.Instance.movementEnabled && Me.CurrentTarget != null && !Me.CurrentTarget.IsDead && (!Me.CurrentTarget.InLineOfSpellSight || !Me.CurrentTarget.IsWithinMeleeRange))
            {
                movement.KingHealMove(Me.CurrentTarget, movement.meelerange);
            }
            return false;
        }

        private bool UseCD()
        {
            if (Me.Combat && Me.GotTarget)
            {
                if (CombatRogueSettings.Instance.CDUse == CombatRogueSettings.CDUseType.COOLDOWN)
                {
                    if (Me.CurrentEnergy <= 20 && utils.CanCast(adrenaline_rush))
                    {
                        utils.LogActivityEnergy("adrenaline_rush");
                        utils.Cast(adrenaline_rush);
                    }
                    if (utils.CanCast(shadow_blades) && (utils.isAuraActive(adrenaline_rush_buff) || utils.isAuraActive(adrenaline_rush)))
                    {
                        utils.LogActivityEnergy("shadow_blades");
                        utils.Cast(shadow_blades);
                    }
                }
                

                if (extra.IsTargetBoss())
                {
                    if (CombatRogueSettings.Instance.CDUse == CombatRogueSettings.CDUseType.BOSS)
                    {
                        if (Me.CurrentEnergy <= 20 && utils.CanCast(adrenaline_rush))
                        {
                            utils.LogActivityEnergy("adrenaline_rush");
                            utils.Cast(adrenaline_rush);
                        }
                        if (utils.CanCast(shadow_blades) && (utils.isAuraActive(adrenaline_rush_buff) || utils.isAuraActive(adrenaline_rush)))
                        {
                            utils.LogActivityEnergy("shadow_blades");
                            utils.Cast(shadow_blades);
                        }
                    }
                }
            }
            return false;
        }

        
    }
}

